home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Special 25 / AMIGAplus Sonderheft 25 (2000)(Falke)(DE)(Track 1 of 4)[!].iso / Updates / PowerPC / CyberFIX / CSPPC233Fix_wos.c < prev    next >
C/C++ Source or Header  |  2000-05-16  |  3KB  |  100 lines

  1. /*
  2. ** CSPPC233Fix_wos.c
  3. **
  4. ** An Instruction Access Exception handler, which tries to recover from
  5. ** a hardware bug on CSPPC/233 cards by fixing the trashed LR register.
  6. **
  7. ** Written by Frank Wille <frank@phoenix.owl.de>.
  8. ** This code is PUBLIC DOMAIN.
  9. **
  10. */
  11.  
  12. #include <stdio.h>
  13. #include <time.h>
  14. #include <dos/dos.h>
  15. #include <powerpc/powerpc.h>
  16. #include <powerpc/tasksPPC.h>
  17. #include <clib/powerpc_protos.h>
  18.  
  19.  
  20. static int sigExcept;                  /* exception notification signal */
  21. static struct EXCContext EC;           /* copy of exception context */
  22. static struct TaskPPC *thisTask;       /* this task */
  23. static struct TaskPPC *excTask;        /* excepting task */
  24.  
  25. ULONG IAccessException(struct EXCContext *);
  26.  
  27. /* This line is vbcc-specific, the rest should be portable (to
  28.    Storm-C, for example). Although I doubt that gcc-WarpOS would
  29.    work, because the exception handler should be PowerOpen-ABI). */
  30. ULONG r2(void) = "\tmr\tr3,r2"; /* gets TOC-pointer */
  31.  
  32.  
  33.  
  34. main()
  35. {
  36.   static ULONG cnt=0;
  37.   struct TagItem ti[8];
  38.   void *xhdl;
  39.   ULONG sigmsk;
  40.  
  41.   if ((sigExcept = AllocSignalPPC(-1)) >= 0) {
  42.     thisTask = FindTaskPPC(NULL);
  43.  
  44.     /* install a global handler for Instruction Access Exceptions */
  45.     ti[0].ti_Tag = EXCATTR_CODE;
  46.     ti[0].ti_Data = (ULONG)IAccessException;
  47.     ti[1].ti_Tag = EXCATTR_DATA;
  48.     ti[1].ti_Data = r2();
  49.     ti[2].ti_Tag = EXCATTR_EXCID;
  50.     ti[2].ti_Data = EXCF_IACCESS;
  51.     ti[3].ti_Tag = EXCATTR_FLAGS;
  52.     ti[3].ti_Data = EXCF_GLOBAL | EXCF_LARGECONTEXT;
  53.     ti[4].ti_Tag = EXCATTR_PRI;
  54.     ti[4].ti_Data = 127;
  55.     ti[5].ti_Tag = EXCATTR_NAME;
  56.     ti[5].ti_Data = (ULONG)"Trashed-LR bug fix for CSPPC/233";
  57.     ti[6].ti_Tag = TAG_DONE;
  58.  
  59.     if (xhdl = SetExcHandler(ti)) {
  60.       printf("Instruction Access exception handler installed.\n"
  61.              "Press CTRL-C to quit.\n");
  62.       do {
  63.         /* wait for an exception or the signal to quit (CTRL-C) */
  64.         sigmsk = WaitPPC((1L<<sigExcept) | (1L<<SIGBREAKB_CTRL_C));
  65.  
  66.         if (sigmsk & (1L<<sigExcept)) {
  67.           /* print exception info */
  68.           time_t tim;
  69.           char buf[32];
  70.  
  71.           time(&tim);
  72.           strftime(buf,sizeof(buf),"%x",localtime(&tim));
  73.           printf("**(%lu) %s  Trashed LR: 0x%08lx  Task: %08lx (%s)\n",
  74.                  ++cnt,buf,EC.ec_LR,(ULONG)excTask,
  75.                  excTask->tp_Task.tc_Node.ln_Name);
  76.         }
  77.       }
  78.       while (!(sigmsk & (1L<<SIGBREAKB_CTRL_C)));
  79.       RemExcHandler(xhdl);
  80.     }
  81.  
  82.     FreeSignalPPC(sigExcept);
  83.   }
  84. }
  85.  
  86.  
  87. ULONG IAccessException(struct EXCContext *ec)
  88. {
  89.   /* first check if this exception was caused by a trashed LR register */
  90.   if (ec->ec_UPC.ec_SRR0 == ec->ec_LR && (ec->ec_LR & 0xf0000000) != 0) {
  91.     CopyMemPPC(ec,&EC,sizeof(struct EXCContext));  /* save exception ctxt. */
  92.     ec->ec_UPC.ec_SRR0 &= 0x0fffffff;  /* fix PC and LR */
  93.     ec->ec_LR &= 0x0fffffff;
  94.     excTask = FindTaskPPC(NULL);
  95.     SignalPPC(thisTask,1L<<sigExcept);  /* show exception info */
  96.     return (EXCRETURN_ABORT);  /* retry instruction access */
  97.   }
  98.   return (EXCRETURN_NORMAL);
  99. }
  100.